package com.ultron.system.wechat.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ultron.common.entity.system.ResultEnum;
import com.ultron.common.exception.ServiceException;
import com.ultron.common.util.Func;
import com.ultron.common.util.WebClientUtils;
import com.ultron.core.component.redis.RedisUtils;
import com.ultron.core.entity.wechat.bo.WechatUserCodeBO;
import com.ultron.core.entity.wechat.vo.WechatUserAuthVO;
import com.ultron.core.entity.wechat.vo.WechatUserPhoneNumberVO;
import com.ultron.system.wechat.config.WechatConfig;
import com.ultron.system.wechat.constant.WechatConstant;
import com.ultron.system.wechat.service.IWechatBaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

/**
 * 标题：WechatBaseServiceImpl
 * 说明：微信相关基础服务实现
 * 时间：2024/3/4
 * 作者：admin
 */
@Service
public class WechatBaseServiceImpl implements IWechatBaseService {
    @Autowired
    private RedisUtils redisUtils;


    @Autowired
    private WechatConfig weChatConfig;




    /**
     * 获取微信授权token
     *
     * @return
     */
    @Override
    public String getAccessToken() {
        String rsp = "";
        //如果未过期
        if (redisUtils.hasKey(WechatConstant.RDS_WECHAT_ACCESSTOKEN_NAME)) {
            rsp = (String) redisUtils.get(WechatConstant.RDS_WECHAT_ACCESSTOKEN_NAME);
        } else {
            WebClientUtils webClientUtils = new WebClientUtils(WechatConstant.WECHAT_BASE_URL);
            String wechatAccessTokenUri = WechatConstant.WECHAT_ACCESSTOKEN_URI
                    .replace("#{appid}",weChatConfig.getAppid())
                    .replace("#{secret}",weChatConfig.getSecret());
            Mono<String> mono = webClientUtils.get(wechatAccessTokenUri, String.class);
            JSONObject result = this.getWechatResult(mono, "获取微信授权token");
            rsp = result.getString("access_token");
            redisUtils.set(WechatConstant.RDS_WECHAT_ACCESSTOKEN_NAME, rsp, 7200);
        }

        return rsp;
    }


    /**
     * 通过code获取用户OpenId
     *
     * @param req
     * @return
     */
    @Override
    public WechatUserAuthVO getUserOpenIdByCode(WechatUserCodeBO req) {
        if (null == req) {
            throw new ServiceException(ResultEnum.PARAM_MISS, "入参不能为空");
        } else {
            if (Func.isEmpty(req.getCode())) {
                throw new ServiceException(ResultEnum.PARAM_MISS, "入参code不能为空");

            }
        }
        WechatUserAuthVO rsp = new WechatUserAuthVO();
        WebClientUtils webClientUtils = new WebClientUtils(WechatConstant.WECHAT_BASE_URL);
        String wechatUserOpenIdUri = WechatConstant.WECHAT_USER_OPENID_URI
                .replace("#{appid}", weChatConfig.getAppid())
                .replace("#{secret}",weChatConfig.getSecret())
                .replace("#{code}",req.getCode());

        Mono<String> mono = webClientUtils.get(wechatUserOpenIdUri, String.class);
        JSONObject result = this.getWechatResult(mono, "通过code获取用户OpenId");
        rsp.setSessionKey(result.getString("session_key"));
        rsp.setUnionid(result.getString("unionid"));
        rsp.setOpenid(result.getString("openid"));
        return rsp;
    }


    /**
     * 通过code获取用户手机号
     *
     * @param req
     * @return
     */
    @Override
    public WechatUserPhoneNumberVO getPhoneNumber(WechatUserCodeBO req) {
        if (null == req) {
            throw new ServiceException(ResultEnum.PARAM_MISS, "入参不能为空");
        } else {
            if (Func.isEmpty(req.getCode())) {
                throw new ServiceException(ResultEnum.PARAM_MISS, "入参code不能为空");

            }
        }
        WechatUserPhoneNumberVO rsp;
        WebClientUtils webClientUtils = new WebClientUtils(WechatConstant.WECHAT_BASE_URL);
        String accesstoken = this.getAccessToken();
        String wechatUserOpenIdUri = WechatConstant.WECHAT_USER_PHONENUMBER_URI
                .replace("#{accesstoken}",accesstoken)
                .replace("#{code}",req.getCode());
        Mono<String> mono = webClientUtils.get(wechatUserOpenIdUri, String.class);
        JSONObject result = this.getWechatResult(mono, "通过code获取用户手机号");
        JSONObject phoneInfo = result.getJSONObject("phone_info");
        rsp = JSON.parseObject(phoneInfo.toJSONString(), WechatUserPhoneNumberVO.class);
        return rsp;
    }




    /**
     * 校验微信请求
     *
     * @param mono
     */
    private JSONObject getWechatResult(Mono<String> mono, String busiName) {
        String monoString = mono.block();
        JSONObject rsp = JSON.parseObject(monoString);
        if (rsp.containsKey("errcode")) {
            throw new ServiceException(busiName + ",调用微信失败!：" + rsp.getString("errcode")+"："+ rsp.getString("errmsg") );
        }
        return rsp;
    }
}
